float4x4 World;
float4x4 View;
float4x4 Projection;
float specularIntensity = 0.0f;
float specularPower = 64.0f;
float2 uv_scale = float2(1, 1);
texture Texture;
int shaderIndex;

float3 diffuseColor = float3(0, 1, 0);
sampler diffuseSampler = sampler_state
{
    Texture = (Texture);
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
    MIPFILTER = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

texture bumpTexture;
sampler bumpSampler = sampler_state
{
	Texture = bumpTexture;
	MAGFILTER = LINEAR;
	MINFILTER = LINEAR;
	MIPFILTER = LINEAR;
	AddressU = Wrap;
	AddressV = Wrap;
};

// TODO: add effect parameters here.

struct VertexShaderInput
{
    float4 Position : POSITION0;
	float3 Normal	: NORMAL0;
	float2 TexCoord	: TEXCOORD0;

    // TODO: add input channels such as texture
    // coordinates and vertex colors here.
};

struct PixelShaderOutput
{
	float4 Color : COLOR0;
	half4 Normal : COLOR1;
	//float4 Depth : COLOR2;
	float4 Depth : COLOR2;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
	float2 TexCoord	: TEXCOORD0;
	float3 Normal	: TEXCOORD1;
	float2 Depth	: TEXCOORD2;
};

struct VertexShaderInputDiffuse
{
    float4 Position : POSITION0;
	float3 Normal	: NORMAL0;
	float3 Color	: COLOR0;
    // TODO: add input channels such as texture
    // coordinates and vertex colors here.
};

struct VertexShaderOutputDiffuse
{
    float4 Position : POSITION0;
	float3 Normal	: TEXCOORD1;
	float2 Depth	: TEXCOORD2;
	float3 Color	: POSITION1;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
	output.TexCoord = input.TexCoord * uv_scale;
	output.Normal = mul(input.Normal, World);
	output.Depth.x = output.Position.z;
	output.Depth.y = output.Position.w;

    return output;
}


VertexShaderOutputDiffuse VertexShaderFunctionDiffuse(VertexShaderInputDiffuse input)
{
    VertexShaderOutputDiffuse output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
	output.Normal = mul(input.Normal, World);
	output.Depth.x = output.Position.z;
	output.Depth.y = output.Position.w;

	output.Color = input.Color;

    return output;
}

PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
{
    PixelShaderOutput output;

	output.Color = tex2D(diffuseSampler, input.TexCoord);
	output.Color.a = specularIntensity;
	output.Normal.rgb = 0.5f * (normalize(input.Normal) + 1.0f);
	output.Normal.a = specularPower;
	output.Depth = input.Depth.x / input.Depth.y;
	return output;
}

PixelShaderOutput PixelShaderFunctionDiffuse(VertexShaderOutputDiffuse input)
{
    PixelShaderOutput output;
	output.Color = half4(input.Color, 1); // half4(diffuseColor.rgb, 1);
	output.Color.a = specularIntensity;
	output.Normal.rgb = 0.5f * (normalize(input.Normal) + 1.0f);
	output.Normal.a = specularPower;
	//output.Depth = input.Position;
	output.Depth = input.Depth.x / input.Depth.y;
	return output;
}

PixelShaderOutput PixelShaderFunctionBump(VertexShaderOutput input)
{
    PixelShaderOutput output;
	float3 bumpValue = tex2D(bumpSampler, input.TexCoord);
	bumpValue = (bumpValue - 0.5f) * 2.0f;

	output.Color = tex2D(diffuseSampler, input.TexCoord);
	output.Color.a = specularIntensity;
	output.Normal.rgb = 0.5f * (bumpValue + 1.0f);
	output.Normal.a = specularPower;
	output.Depth = input.Depth.x / input.Depth.y;
	return output;
}

PixelShader shaders[3] =
{
compile ps_3_0 PixelShaderFunction(),
compile ps_3_0 PixelShaderFunctionDiffuse(),
compile ps_3_0 PixelShaderFunctionBump()
};
VertexShader vShaders[3] =
{
compile vs_3_0 VertexShaderFunction(),
compile vs_3_0 VertexShaderFunctionDiffuse(),
compile vs_3_0 VertexShaderFunction()
};

technique Technique1
{
    pass Pass1
    {
        // TODO: set renderstates here.

        VertexShader = (vShaders[shaderIndex]);
		PixelShader = (shaders[shaderIndex]);
        //PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
